package com.gao.ranklist.service;

import com.gao.ranklist.constant.Constants;
import com.gao.ranklist.po.HotSearchData;
import com.gao.ranklist.util.RedisUtil;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.*;

/**
 * 百度热搜数据爬虫实现类
 */
@Service
public class BaiduHotSearchSpiderService {

    @Autowired
    private RedisUtil redisUtil;

    /**
     * 初始化热榜数据存入 redis 中
     */
    public void initData() {
        List<HotSearchData> hotSearchData = handleHotData();
        SaveDataIntoZset(hotSearchData);
    }

    /**
     * 将数据存入 redis 中
     * @param hotSearchDataList
     */
    public void SaveDataIntoZset(List<HotSearchData> hotSearchDataList) {
        for (int i = 0; i < hotSearchDataList.size(); i++) {
            HotSearchData hotSearchData = hotSearchDataList.get(i);
            String hotTitle = hotSearchData.getHotTitle();
            int hotIndex = hotSearchData.getHotIndex();
            redisUtil.zAdd(Constants.HOT_SEARCH, hotTitle, hotIndex);
        }
    }

    /**
     * 对爬取的数据合并
     * @param
     * @return
     */
    public List<HotSearchData> handleHotData() {
        // 获取百度热榜数据
        List<String> typeList = new ArrayList<>();
        typeList.add("爱情");
        typeList.add("喜剧");
        typeList.add("动作");
        typeList.add("动画");
        typeList.add("剧情");
        typeList.add("科幻");
        typeList.add("恐怖");
        typeList.add("犯罪");
        typeList.add("惊悚");

        List<HotSearchData> allData = new ArrayList<>();
        for (int i = 0; i < typeList.size(); i++) {
            List<HotSearchData> hotSearchData = parseBaiduHotSearch(typeList.get(i));
            allData.removeAll(hotSearchData);
            allData.addAll(hotSearchData);
        }

        return allData;
    }

    /**
     * 爬取百度热搜页面
     * @param type 类型
     * @return
     * @throws IOException
     */
    public List<HotSearchData> parseBaiduHotSearch(String type) {
        List<HotSearchData> hotSearchDataList = new ArrayList<>();
        HotSearchData hotSearchData;
        String url = "https://top.baidu.com/board?";
        String param = "{\"category\":\""+type+"\",\"country\":\"全部地区\"}";
        Map<String, String> dataMap = new HashMap<>();
        dataMap.put("platform", "pc");
        dataMap.put("tab", "movie");
        dataMap.put("tag", param);
        Document document = null;
        try {
            document = Jsoup
                    .connect(url).ignoreContentType(true).data(dataMap)
                    .header("Accept", "*/*")
                    .header("Accept-Encoding", "gzip, deflate")
                    .header("Accept-Language","zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3")
                    .header("Content-Type", "application/json;charset=UTF-8")
                    .header("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36")
                    .timeout(3000).get();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 调用网页方法
        Element element = document.getElementsByClass("container-bg_lQ801").get(0);
        // 获取所有排行元素
        Elements elements = element.getElementsByClass("category-wrap_iQLoo ");
        for (Element el : elements) {
            // 获取标题
            String hotTitle = el.getElementsByClass("c-single-text-ellipsis").get(0).text();
            // 获取热搜指数
            String hotIndex = el.getElementsByClass("hot-index_1Bl1a").get(0).text();
            hotSearchData = new HotSearchData();
            int ihotIndex = Integer.valueOf(hotIndex.trim()) / 1000;
            if (ihotIndex > 0) {
                hotSearchData.setHotTitle(hotTitle);
                hotSearchData.setHotIndex(Integer.valueOf(hotIndex.trim()) / 100);
                //hotSearchData.setHotIndex(new Random().nextInt(100));

                hotSearchDataList.add(hotSearchData);
            }
        }

        return hotSearchDataList;
    }
}
